#ifndef GAMEENGINE_MULTIMEDIA_MUSIC_OBSERVER_H
#define GAMEENGINE_MULTIMEDIA_MUSIC_OBSERVER_H

#include <GameEngine/Multimedia/multimedia_settings.h>

#include <GameEngine/Multimedia/music.h>

#include <QtCore/QTimer>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//=================================================================================


//! Observes the state of a music player at user-defined time intervals
/*!
 *  The refresh rate directly affects performance of the observer - the more often the
 *  state of the music is queried, the lower the performance. Hence, it is recommended
 *  to set the refresh rate to the lowest possible frequency (i.e., the largest possible
 *  time interval) in order to limit performance issues.<br>
 *  Unless the program needs very fast response after the music changes its state, we
 *  advise to choose a refresh rate between 500 milliseconds and 1 second.
 *
 *  Please note that the music observer is attached to a specific Music instance. This
 *  implies that the observer is destroyed when the Music instance is destroyed, but the
 *  internal music player may still be alive if other Music instances are still using
 *  it. See the Music class documentation for more information on the resource management
 *  of the Music class.
 */
class _Multimedia_decl MusicObserver : public QTimer {
	Q_OBJECT

public:
	//! Typedef used for durations specified in milliseconds
	typedef int MilliSeconds;

public:
	virtual ~MusicObserver();
	static MusicObserver* create_observer(MilliSeconds refresh_rate, const Music& music);

	void set_refresh_rate(MilliSeconds refresh_rate);

	const Music* music() const;

signals:
	//! Signal emitted when the music starts / resumes playing
	void music_started() const;

	//! Signal emitted when the music is paused
	void music_paused() const;

	//! Signal emitted when the music is stopped
	void music_stopped() const;

	//! Signal emitted when the music player gets invalid
	void music_invalid() const;

	//! Signal emitted when the music player is destroyed
	/*!
	 @note The destruction of the observer immediately follows the destruction
	       of the music player
	 */
	void music_destroyed() const;

private slots:
	void refresh();
	void clean();

private:
	MusicObserver(MilliSeconds refresh_rate, const Music& music);

private:
	//! Default constructor
	/*!
	 @note This method is defined, but not implemented, in order to force client
	       code to use the MusicObserver API
	 */
	MusicObserver();

	//! Copy constructor
	/*!
	 @note This method is defined, but not implemented, in order to force client
	       code to use the MusicObserver API
	 */
	MusicObserver(const MusicObserver& rhs);

	//! Assignment operator
	/*!
	 @note This method is defined, but not implemented, in order to force client
	       code to use the MusicObserver API
	 */
	MusicObserver& operator=(const MusicObserver& rhs);

private:
	//! Music player
	const Music* music_;

	//! Previous state of the music player
	Music::PlayerState previous_state_;
};

//========================================================

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif
